/*日志缓冲区类设计*/
#pragma once
#include <cassert>
#include <string>
#include <vector>
#include "Util.hpp"

extern mylog::Util::JsonData* g_conf_data; //g_conf_data 是全局配置数据，存储了日志系统的一些参数；这个指针在程序启动时会被初始化，Buffer 需要依赖这些配置。

namespace mylog{
    class Buffer{
    public:
        Buffer() : write_pos_(0), read_pos_(0) { //构造函数，初始换读和写的位置为0；缓冲区的大小初始化为配置文件中的 buffer_size。write写入就是生产者，read读取就是消费者
            buffer_.resize(g_conf_data->buffer_size);
        }

        void Push(const char *data, size_t len) // Push 用来往缓冲区写数据；调用 ToBeEnough 检查剩余空间，不够就扩容；写完后更新写指针 write_pos_
        {
            ToBeEnough(len); // 确保容量足够
            // 开始写入
            std::copy(data, data + len, &buffer_[write_pos_]);
            write_pos_ += len;
        }
        char *ReadBegin(int len) //返回一个指向待读取数据的指针；这里没有直接移动 read_pos_，只是返回一个地址，调用者要手动调用 MoveReadPos(len) 来推进。
        {
            assert(len <= ReadableSize());
            return &buffer_[read_pos_];
        }
        bool IsEmpty() { return write_pos_ == read_pos_; } // 判断缓冲区是否为空。

        void Swap(Buffer &buf) // 交换两个 Buffer 对象的内容，传入的buf是另一个缓冲区
        {
            buffer_.swap(buf.buffer_);
            std::swap(read_pos_, buf.read_pos_);
            std::swap(write_pos_, buf.write_pos_);
        }

        size_t WriteableSize() // 还可以写多少字节。
        { // 写空间剩余容量
            return buffer_.size() - write_pos_;
        }
        size_t ReadableSize() // 可以读多少字节。
        { // 读空间剩余容量
            return write_pos_ - read_pos_;
        }
        const char *Begin() { return &buffer_[read_pos_]; }

        // 手动调整写指针和读指针
        void MoveWritePos(int len)
        {
            assert(len <= WriteableSize());
            write_pos_ += len;
        }
        void MoveReadPos(int len)
        {
            assert(len <= ReadableSize());
            read_pos_ += len;
        }
        void Reset() // 相当于清空缓冲区（不是真的释放内存，只是重置指针）。
        { // 重置缓冲区
            write_pos_ = 0;
            read_pos_ = 0;
        }

    protected:
        void ToBeEnough(size_t len) //自动扩容；检查是否有足够空间写 len 个字节。
        {
            int buffersize = buffer_.size();
            if (len >= WriteableSize())
            {
                if (buffer_.size() < g_conf_data->threshold) // 小于阈值时：用 指数扩容（new_size = old_size * 2 + old_size），增长很快。
                {
                    buffer_.resize(2 * buffer_.size() + buffersize);
                }
                else
                {
                    buffer_.resize(g_conf_data->linear_growth + buffersize); // 超过阈值时：用 线性扩容（new_size = old_size + linear_growth），避免内存无限膨胀。
                }
            }
        }

    protected:
        std::vector<char> buffer_; // 缓冲区
        size_t write_pos_;         // 生产者此时的位置
        size_t read_pos_;          // 消费者此时的位置
    };
} // namespace mylog